package com.A21.GuoSai.demo.atom_adjust.utils;

import com.A21.GuoSai.demo.service_entity.entity.atom.AtomServicePojo;
import io.camunda.zeebe.client.api.worker.JobHandler;
import io.camunda.zeebe.client.impl.ZeebeClientImpl;
import io.camunda.zeebe.client.impl.worker.JobRunnableFactory;
import io.camunda.zeebe.spring.client.ZeebeClientLifecycle;
import io.camunda.zeebe.spring.client.bean.MethodInfo;
import io.camunda.zeebe.spring.client.bean.value.ZeebeWorkerValue;

import java.io.Closeable;
import java.lang.reflect.Field;
import java.util.List;

/**
 * 利用反射机制提取出ZeebeWorkerValue或其他相关信息
 */
public class AtomServiceUtils {

    //  将ZeebeWorkerValue转换成AtomServicePojo
    public static AtomServicePojo castToAtomService(ZeebeWorkerValue workerValue){
        MethodInfo methodInfo=workerValue.getMethodInfo();
        String methodMess=methodInfo.getBean().getClass().getCanonicalName()+"."+methodInfo.getMethodName();
        return new AtomServicePojo(workerValue.getType(), workerValue.getName(),methodMess);
    }

    public static List<Closeable> getJobWorkerImpl(ZeebeClientLifecycle clientLifecycle) throws NoSuchFieldException, IllegalAccessException {
        //获取父类的delegate域
        Field field =clientLifecycle.getClass().getSuperclass().getDeclaredField("delegate");
        //开启权限许可
        field.setAccessible(true);
        //取出对象clientLifecycle中delegate域对应的对象，即zeebeCilentImpl
        ZeebeClientImpl zeebeClientImpl= (ZeebeClientImpl) field.get(clientLifecycle);
        //继续取出zeebeClientImpl中的参数信息，源码中没有提供get/set方法，只能硬读取了
        Field listfield=zeebeClientImpl.getClass().getDeclaredField("closeables");
        listfield.setAccessible(true);
        //这里拿到的只是JobWorkerImpl对象数组，里面还不是ZeebeWorkerValue
        return  (List<Closeable>) listfield.get(zeebeClientImpl);
    }

    //从JobWorker中提取jobHandler
    public static JobHandler getJobHandler(Closeable closeable) throws NoSuchFieldException, IllegalAccessException {
        //获取jobRunnableFactory
        Field jobRunFactory=closeable.getClass().getDeclaredField("jobHandlerFactory");
        jobRunFactory.setAccessible(true);
        JobRunnableFactory jobRunnableFactory= (JobRunnableFactory) jobRunFactory.get(closeable);
        //获取jobHandler
        Field handler=jobRunnableFactory.getClass().getDeclaredField("handler");
        handler.setAccessible(true);
        return (JobHandler) handler.get(jobRunnableFactory);
    }

    //从JobWorker中提取出workvalue
    public static ZeebeWorkerValue getWorkerValueFromJobWorker(Closeable closeable) throws NoSuchFieldException, IllegalAccessException {
        JobHandler jobHandler = AtomServiceUtils.getJobHandler(closeable);
        //获取ZeebeWorkerValue
        Field workvalue= jobHandler.getClass().getDeclaredField("workerValue");
        workvalue.setAccessible(true);
        return (ZeebeWorkerValue) workvalue.get(jobHandler);
    }
}
